package org.javaboy.storage.service;

import io.seata.rm.tcc.api.BusinessActionContext;
import org.javaboy.storage.mapper.StorageMapper;
import org.javaboy.storage.model.Commodity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

@Service
public class StorageService {
    @Autowired
    StorageMapper storageMapper;

    /**
     * 预控库存，冻结
     *
     * @param commodityCode
     * @param count
     * @return
     */
    @Transactional
    public boolean deduce(Integer commodityCode, Integer count) {
        Commodity commodity = storageMapper.getCommodity(commodityCode);
        if (null == commodity) {
            return false;
        }
        if (commodity.getCount() < count) {
            return false;
        }
        commodity.setCount(commodity.getCount() - count);
        commodity.setFreeze(commodity.getFreeze() + count);
        return storageMapper.deduce(commodity) == 1;
    }

    /**
     * 确认库存，真的扣除库存
     * <p>
     * 二阶段的这个方法是由系统去自动调用的，系统为了确保整个方法执行成功，会自动重试（如果发生失败）
     * <p>
     * 自动重试意味着必须要处理幂等性
     *
     * @param actionContext
     * @return
     */
    public boolean commit(BusinessActionContext actionContext) {
        Integer commodityCode = ((Integer) actionContext.getActionContext("commodityCode"));
        Integer count = ((Integer) actionContext.getActionContext("count"));
        //确认库存，真正扣除库存
        Commodity commodity = storageMapper.getCommodity(commodityCode);
        if (commodity.getFreeze() < count) {
            return true;
        }
        commodity.setFreeze(commodity.getFreeze() - count);
        return storageMapper.deduce(commodity) == 1;
    }

    /**
     * 取消库存，恢复库存，解冻
     *
     * @param actionContext
     * @return
     */
    public boolean rollback(BusinessActionContext actionContext) {
        Integer commodityCode = ((Integer) actionContext.getActionContext("commodityCode"));
        Integer count = ((Integer) actionContext.getActionContext("count"));
        Commodity commodity = storageMapper.getCommodity(commodityCode);
        if (commodity.getFreeze() >= count) {
            commodity.setFreeze(commodity.getFreeze() - count);
            commodity.setCount(commodity.getCount() + count);
            return storageMapper.deduce(commodity) == 1;
        }
        return true;
    }
}
